import re
from django import http
from django.contrib.auth import login
from django.views import View
from apps.users.models import User
from django.contrib.auth import login, authenticate, logout
import json
from meiduosy.utils.view import LoginRequiredMixin
from celery_tasks.email.tasks import send_verify_email
from apps.users.utils import generate_verify_email_url

#邮箱验证
class VerifyEmailView(View):
    """验证邮箱"""

    def put(self, request):
        """实现邮箱验证逻辑"""
        # 接收参数
        token = request.GET.get('token')

        # 校验参数：判断 token 是否为空和过期，提取 user
        if not token:
            return http.JsonResponse({'code':400,
                                  'errmsg':'缺少token'})

        # 调用上面封装好的方法, 将 token 传入
        user = User.check_verify_email_token(token)
        if not user:
            return http.JsonResponse({'code':400,
                                  'errmsg':'无效的token'})

        # 修改 email_active 的值为 True
        try:
            user.email_active = True
            user.save()
        except Exception as e:
            # logger.error(e)
            return http.JsonResponse({'code':400,
                                  'errmsg':'激活邮件失败'})

        # 返回邮箱验证结果
        return http.JsonResponse({'code':0,
                                  'errmsg':'ok'})
#添加邮箱
class EmailView(View):
    """添加邮箱"""

    def put(self, request):
        """实现添加邮箱逻辑"""
        # 接收参数
        json_dict = json.loads(request.body.decode())
        email = json_dict.get('email')

        # 赋值 email 字段
        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            # logger.error(e)
            return http.JsonResponse({'code': 400,
                                      'errmsg': '添加邮箱失败'})
        verify_url =generate_verify_email_url(self, request)
        send_verify_email.delay(email, verify_url)

        # 响应添加邮箱结果
        return http.JsonResponse({'code': 0,
                                  'errmsg': 'ok'})
#用户中心
class UserInfoView(LoginRequiredMixin,  View):
    """用户中心"""
    def get(self, request):
        """提供个人信息界面"""
        # 获取界面需要的数据,进行拼接
        info_data = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'email': request.user.email,
            'email_active': request.user.email_active
        }

        return http.JsonResponse({
            'code': 0,
            'errmsg': '个人中心',
               'info_data':info_data
            })
#退出登录
class LogoutView(View):
    """定义退出登录的接口"""

    def delete(self, request):
        """实现退出登录逻辑"""

        # 清理 session
        logout(request)

        # 创建 response 对象.
        response = http.JsonResponse({'code':0,
                                      'errmsg':'ok'})

        # 调用对象的 delete_cookie 方法, 清除cookie
        response.delete_cookie('username')

        # 返回响应
        return response
#用户名登录
class LoginView(View):

    def post(self, request):
        '''实现登录接口'''
        # 1.接收参数
        dict = json.loads(request.body.decode())
        username = dict.get('username')
        password = dict.get('password')
        remembered = dict.get('remembered')


        # 2.校验(整体 + 单个)
        if not all([username, password]):
            return http.JsonResponse({'code': 400,
                                      'errmsg': '缺少必传参数'})

        # 3.验证是否能够登录
        user = authenticate(username=username,
                            password=password)

        # 判断是否为空,如果为空,返回
        if user is None:
            return http.JsonResponse({'code': 400,
                                      'errmsg': '用户名或者密码错误'})

        # 4.状态保持
        login(request, user)

        # 5.判断是否记住用户
        if remembered != True:
            # 7.如果没有记住: 关闭立刻失效
            request.session.set_expiry(0)
        else:
            # 6.如果记住:  设置为两周有效
            request.session.set_expiry(None)

        # 8.返回json
        # return http.JsonResponse({'code': 0,
        #                          'errmsg': 'ok'})
        response = http.JsonResponse({'code': 0, 'errmsg': 'ok'})

        # 在响应对象中设置用户名信息.
        # 将用户名写入到 cookie，有效期 14 天
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)

        # 返回响应结果
        return response
#判断手机号是否重复注册
class MobileCountView(View):

    def get(self, request, mobile):
        '''判断手机号是否重复注册'''
        # 1.查询mobile在mysql中的个数
        try:
            count = User.objects.filter(mobile=mobile).count()
        except Exception as e:
            return http.JsonResponse({'code':400, 'errmsg':'查询数据库出错'})

        # 2.返回结果(json)
        return http.JsonResponse({'code':0, 'errmsg':'ok', 'count':count})
#判断用户名是否重复
class UsernameCountView(View):
    """判断用户名是否重复注册"""

    def get(self, request, username):
        '''判断用户名是否重复'''
        # 1.查询username在数据库中的个数
        try:
            count = User.objects.filter(username=username).count()
        except Exception as e:
            return http.JsonResponse({'code':400, 'errmsg':'访问数据库失败'})

        # 2.返回结果(json) ---> code & errmsg & count
        return http.JsonResponse({'code': 0, 'errmsg': 'ok', 'count':count})
#注册实现
class RegisterView(View):
    def post(self, request):
        '''接收参数, 保存到数据库'''
         # 1.接收参数：请求体中的JSON数据 request.body
        json_bytes = request.body # 从请求体中获取原始的JSON数据，bytes类型的
        json_str = json_bytes.decode() # 将bytes类型的JSON数据，转成JSON字符串
        json_dict = json.loads(json_str) # 将JSON字符串，转成python的标准字典
        # json_dict = json.loads(request.body.decode())

        # 提取参数
        username = json_dict.get('username')
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        mobile = json_dict.get('mobile')
        allow = json_dict.get('allow')
        sms_code = json_dict.get('sms_code')

        # 2.校验(整体参数是否为空)
        if not all([username, password, password2, mobile, sms_code]):
            return http.JsonResponse({'code':400, 'errmsg':'缺少必传参数!'})

        # 3.username检验
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.JsonResponse({'code': 400, 'errmsg': 'username格式有误!'})

        # 4.password检验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.JsonResponse({'code': 400, 'errmsg': 'password格式有误!'})

        # 5.password2 和 password
        if password != password2:
            return http.JsonResponse({'code': 400, 'errmsg': '两次输入不对!'})
        # 6.mobile检验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'code': 400, 'errmsg': 'mobile格式有误!'})
        # 7.allow检验
        if allow != True:
            return http.JsonResponse({'code': 400, 'errmsg': 'allow格式有误!'})


        # 8.注册的核心逻辑-保存到数据库 (username password mobile)
        try:
            user = User.objects.create_user(username=username,
                                             password=password,
                                             mobile=mobile)
        except Exception as e:
            return http.JsonResponse({'code': 400, 'errmsg': '注册失败!'})
        login(request, user)
        # 13.拼接json返回
        return http.JsonResponse({'code': 0, 'errmsg': '注册成功!'})